package com.campus.common.service.impl;

import com.campus.common.domain.Product;
import com.campus.common.domain.order.Order;
import com.campus.common.domain.order.OrderItem;
import com.campus.common.dto.order.OrderDto;
import com.campus.common.dto.order.OrderItemDto;
import com.campus.common.mapper.OrderMapper;
import com.campus.common.mapper.ProductMapper;
import com.campus.common.service.OrderService;
import com.campus.common.service.UserService;
import com.campus.common.utils.IdGenerator;
import com.campus.common.utils.RedisCache;
import com.campus.common.vo.OrderVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @program: campus
 * @description:
 * @author: ENDING
 * @create: 2024-04-25 23:45
 **/

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private RedisCache redisCache;

    @Override
    public int insertOrderTest(OrderDto orderDto) {
        return 0;
    }

    @Override
    public OrderVo createOrder(OrderDto orderDto) {
        Integer userId = UserService.getUserId();
        redisCache.deleteObject("order:all:" + userId.toString());

        Order order = new Order();
        ArrayList<OrderItem> orderItems = new ArrayList<>();
        BeanUtils.copyProperties(orderDto, order);
        order.setOrderId(IdGenerator.generateId());

        // 订单总价格price
        BigDecimal price = new BigDecimal(0).setScale(2, RoundingMode.HALF_UP);
        ArrayList<Product> itemProducts = new ArrayList<>();
        for (OrderItemDto orderItemDto : orderDto.getOrderItemList()) {
            Product productTemp  = productMapper.selectProduct(orderItemDto.getProductId());

            // 计算订单中小项价格（price * discount * amount）
            BigDecimal productRealPrice = productTemp.getDiscount().multiply(productTemp.getPrice()).setScale(2, RoundingMode.HALF_UP);
            BigDecimal priceTemp = productRealPrice.multiply(BigDecimal.valueOf(orderItemDto.getAmount())).setScale(2, RoundingMode.HALF_UP);
            price = price.add(priceTemp);

            // 生成订单小项
            OrderItem orderItem = new OrderItem();
            orderItem.setItemId(IdGenerator.generateId());
            orderItem.setOrderId(order.getOrderId());
            orderItem.setPrice(productRealPrice);
            orderItem.setAmount(orderItemDto.getAmount());
            orderItem.setSumPrice(priceTemp);
            orderItem.setProductId(orderItemDto.getProductId());
            orderItems.add(orderItem);
            orderMapper.insertOrderItem(orderItem);
        }

        order.setPrice(price);
        order.setGmtCreate(LocalDateTime.now());
        order.setGmtModified(LocalDateTime.now());

        OrderVo orderVo = new OrderVo(order, orderItems);
        orderVo.initOrder();
        redisCache.setCacheObject("order:unpay:"+order.getOrderId().toString(), orderVo, 30, TimeUnit.MINUTES);

        orderMapper.insertOrder(order);

        return orderVo;
    }

    @Override
    public OrderVo payOrder(Long orderId) {

        OrderVo order = redisCache.getCacheObject("order:unpay:" + orderId.toString());
        Integer userId = UserService.getUserId();
        redisCache.deleteObject("order:all:" + userId.toString());
        if(order != null) {
            order.getOrder().setIsPay(1);
            orderMapper.orderPay(orderId, LocalDateTime.now());
            order.getOrder().setGmtModified(LocalDateTime.now());
            redisCache.deleteObject("order:unpay:" + orderId.toString());
            redisCache.setCacheObject("order:is_pay:"+orderId.toString(), order, 3, TimeUnit.DAYS);
            return order;
        }
        return null;
    }

    @Override
    public boolean deleteOrder(Long orderId) {

        Integer userId = UserService.getUserId();

        // redis
        redisCache.deleteObject("order:unpay:" + orderId.toString());
        redisCache.deleteObject("order:is_pay:" + orderId.toString());
        redisCache.deleteObject("order:all:" + userId.toString());

        // 数据库
        return orderMapper.orderDelete(orderId, LocalDateTime.now()) != 0;
    }

    @Override
    public List<OrderVo> getAllOrder(Long userId) {

        // 先从缓存中搜索
        List<OrderVo>  orderVoList= redisCache.getCacheObject("order:all:" + userId.toString());

        if(orderVoList == null || orderVoList.size() == 0) {
            orderVoList = new ArrayList<>();
            List<Order> orderList = orderMapper.selectAllOrder(userId);
            for (Order order : orderList) {
                OrderVo orderVo = new OrderVo(order, orderMapper.selectAllItem(order.getOrderId()));
                orderVoList.add(orderVo);
            }

            // 加入缓存
            redisCache.setCacheObject("order:all:"+userId.toString(), orderVoList, 1, TimeUnit.HOURS);
        }

        return orderVoList;
    }
}
